package com.itheima.distributed;

import com.google.gson.Gson;
import com.itheima.pojo.News;
import com.itheima.pojo.SpiderFinal;
import com.itheima.tools.HttpClientUtils;
import com.itheima.tools.IdWorker;
import com.itheima.tools.JedisUtil;
import redis.clients.jedis.Jedis;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 除了保存之外的所有功能,封装到这里
 * 腾讯爬虫的master程序：
 * 获取新闻(热点和非热点新闻)数据json,
 * 解析json数据转换成List<News>对象，
 */
public class NewsTencentMaster {
        /*
            首先是Gson和id生成器
         */
    private static Gson gson = new Gson();
    /*
        这边的id生成器直接给了一个2,因为163的封装jar会采取集群的方式来提升效率
        那么就会占用0(默认)和1 两个工作站的地址,这边为了防止冲突,直接设置为2
     */
    private static IdWorker idWorker = new IdWorker(2,0);

    public static void main(String[] args) throws IOException {
        //1. 确定爬取的url
        String hotUrl = "https://pacaio.match.qq.com/irs/rcd?cid=137&token=d0f13d594edfc180f5bf6b845456f3ea&id=&ext=ent&num=60";

        String noHotUrl = "https://pacaio.match.qq.com/irs/rcd?cid=146&token=49cbb2154853ef1a74ff4e53723372ce&ext=ent&page=0";


        //2.分页爬取
        pageTencent(hotUrl,noHotUrl);

    }

    /**
     * 分页爬取方法
     * @param hotUrl
     * @param noHotUrl
     */
    private static void pageTencent(String hotUrl, String noHotUrl) throws IOException {
        //1 处理热点新闻 发送请求,生成json数据
        String hotJson = HttpClientUtils.doGet(hotUrl);
        //解析json数据
        List<News> hotNewsList = parseJsonNews(hotJson);
        //把返回的list数据写入redis集合中
        saveNewsListToRedis(hotNewsList);

    }

    /**
     * 把数据保存到redis数据库中去
     * @param hotNewsList
     */
    private static void saveNewsListToRedis(List<News> hotNewsList) {
        for (News news : hotNewsList) {
            Jedis jedis = JedisUtil.getJedis();
            //lpush 队列的方式存入,存到常量表示新闻数据,数据是通过gson转换的json字符串
            jedis.lpush(SpiderFinal.SPIDER_NEWS_NEWJSONLIST,gson.toJson(news));
            jedis.close();
        }
    }

    /**
     * 解析url,返回list新闻列表
     * @param JsonNews
     * @return
     */
    private static List<News> parseJsonNews(String JsonNews) {
        List<News> newsList = new ArrayList<News>();
        //返回的列表存给map,json字符串键值形式
        Map<String,Object> map = gson.fromJson(JsonNews, Map.class);
        //获取回来的单个新闻是map,但是有多个,所以是List中Map
        List<Map<String , Object>> data = (List<Map<String, Object>>) map.get("data");
        for (Map<String, Object> news : data) {
            News newsBean = new News();
            //获取url
            String docurl = (String) news.get("vurl");
            //进行过滤,如果是视频文件
            if(docurl.contains("video") || !docurl.contains("new.qq.com/omn")){
                continue;
            }
            //判断这个url是否已经爬取过
            boolean hasParsed = isParsedDocUrl(docurl);
            if(hasParsed){
                continue;
            }

            System.out.println("docurl：" + docurl);

            //标题
            String title = (String) news.get("title");
            System.out.println("标题：" + title);

            //时间
            String time = (String) news.get("update_time");


            //来源
            String source = (String) news.get("source");

            //编辑==来源

            //内容
            String content = (String) news.get("intro");

            newsBean.setId(idWorker.nextId() + "");
            newsBean.setTitle(title);
            newsBean.setSource(source);
            newsBean.setTime(time);
            newsBean.setContent(content);
            newsBean.setEditor(source);
            newsBean.setDocurl(docurl);

            //添加到list列表
            newsList.add(newsBean);
        }

        return newsList;
    }

    /**
     * 判断给定的url是否已经爬取过
     * @param docurl ： 判断的url
     * @return
     */
    private static boolean isParsedDocUrl(String docurl) {
        //1. 获取jedis连接
        Jedis jedis = JedisUtil.getJedis();

        //2. 判断是否在set集合中
        Boolean sismember = jedis.sismember(SpiderFinal.SPIDER_NEWS_URLSET, docurl);

        //3.关闭
        jedis.close();

        //4.返回
        return sismember;
    }

}
